package autosession

import (
	"bytes"
	"encoding/gob"
	"encoding/json"
	"fmt"
)

// SessionSerializer provides an interface hook for alternative serializers
type SessionSerializer interface {
	Deserialize(d []byte) (map[string]string, error)
	Serialize(values map[string]string) ([]byte, error)
}

// JSONSerializer encode the session map to JSON.
type JSONSerializer struct{}

func (s JSONSerializer) Serialize(values map[string]string) ([]byte, error) {
	if values == nil {
		return nil, fmt.Errorf("session values is nil")
	}
	return json.Marshal(values)
}

func (s JSONSerializer) Deserialize(d []byte) (map[string]string, error) {
	var values map[string]string
	err := json.Unmarshal(d, &values)
	if err != nil {
		return nil, err
	}
	return values, nil
}

// GobSerializer uses gob package to encode the session map
type GobSerializer struct{}

func (s GobSerializer) Serialize(values map[string]string) ([]byte, error) {
	buf := new(bytes.Buffer)
	enc := gob.NewEncoder(buf)
	err := enc.Encode(values)
	if err == nil {
		return buf.Bytes(), nil
	}
	return nil, err
}

func (s GobSerializer) Deserialize(d []byte) (map[string]string, error) {
	dec := gob.NewDecoder(bytes.NewBuffer(d))
	var values map[string]string
	err := dec.Decode(&values)
	return values, err
}
